package com.ruoyi.web.controller.api;



import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.cat.domain.*;
import com.ruoyi.cat.domain.DTO.AppIdDTO;
import com.ruoyi.cat.domain.VO.AppIdVO;
import com.ruoyi.cat.domain.VO.LoginVO;
import com.ruoyi.cat.domain.VO.WxUserVO;
import com.ruoyi.cat.service.*;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.WxLoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.Base64Util;
import com.ruoyi.common.utils.OrderUtil;
import com.ruoyi.common.utils.ReferralCodeGenerator;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.wxpay.AppletsWxLoginRO;
import com.ruoyi.common.wxpay.WxLoginUtil;
import com.ruoyi.common.wxpay.WxUserInfoRO;
import com.ruoyi.framework.web.service.WxTokenService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import reactor.core.publisher.Flux;

@Api(tags = "api-登录相关接口")
@RestController
@RequestMapping("/api/login")
@Slf4j
public class LoginController  extends BaseController {

    @Value("${wechat.appid}")
    private String appid;

    @Value("${wechat.secret}")
    private String secret;

    @Value("${wechat.appid1}")
    private String appid1;

    @Value("${wechat.secret1}")
    private String secret1;

    @Autowired
    private ICatUserbasicTableService iCatUserbasicTableService;


    @Autowired
    private WxTokenService wxTokenService;


    @Autowired
    private RedisCache redisCache;


    @Autowired
    private ICatActivityTableService iCatActivityTableService;

    @Autowired
    private ICatChanceService catChanceService;

    @Autowired
    private ICatShareuserTableService catShareuserTableService;



    // Redis中token的key前缀
    private static final String TOKEN_KEY_PREFIX = "weixin:access_tokenLogin:";
    // token有效期为7200秒(2小时)，我们可以提前5分钟刷新
    private static  Integer EXPIRE_SECONDS = 7200;

    private static final long REFRESH_BEFORE_EXPIRE = 300;

   //IpUtils.getHostIp()  获取ip


    @ApiOperation("微信授权登录")
    @PostMapping("login")
    public AjaxResult login(@Validated @RequestBody LoginVO loginVO){

        logger.info("微信登录==== {} ",loginVO);
        getOpenId(loginVO.getCode());
        JSONObject jsonObject = getAccessToken(loginVO.getCode());
        logger.info("jsonObject-------------{}",jsonObject.toJSONString());
        WxUserInfoRO wxUserInfoRO = WxLoginUtil.toWxLogin(loginVO.getCode(),appid,secret);
        AppletsWxLoginRO wxUser = WxLoginUtil.toAppletsWxLogin(loginVO.getCode(),appid,secret);


        String accessToken = jsonObject.getString("access_token");
        String openid = jsonObject.getString("openid");
        JSONObject jsonObject1 = getUserinfo(accessToken, openid);

        log.info("login登录相关的内容====--------{}",jsonObject1.toJSONString());
        logger.info("微信登录-------------{}",wxUser);
        Map<String, String> map1 = new HashMap<>();
        WxLoginUser wxLoginUser = new WxLoginUser();
        CatUserbasicTable catUserbasicTable = iCatUserbasicTableService.selectCatUserbasicTableByOpenId(loginVO.getOpenId());
        if (catUserbasicTable == null) {
            catUserbasicTable = new CatUserbasicTable();
            catUserbasicTable.setOpenId(loginVO.getOpenId());
            if (StringUtils.isNotEmpty(loginVO.getType())&&loginVO.getType().equals("2")){
                catUserbasicTable.setNickName("微信用户");
            }else{
                catUserbasicTable.setNickName(wxUserInfoRO.getNickname());
            }
//            if (jsonObject1 != null && jsonObject1.containsKey("headimgurl") && jsonObject1.containsKey("nickname")) {
//                String headimgurl = jsonObject1.getString("headimgurl");
//                String nickname = jsonObject1.getString("nickname");
//                catUserbasicTable.setProfileImg(headimgurl);
//                catUserbasicTable.setNickName(nickname);
//                log.info("catUserbasicTable登录相关的内容====--------{}",catUserbasicTable);
//                iCatUserbasicTableService.updateCatUserbasicTable(catUserbasicTable);
//            }
            catUserbasicTable.setProfileImg(wxUserInfoRO.getHeadimgurl());
            catUserbasicTable.setReferenceId(loginVO.getReferenceId());
            catUserbasicTable.setReferenceNum(ReferralCodeGenerator.generateReferralCode());
            catUserbasicTable.setType(loginVO.getType());
            if (StringUtils.isNotEmpty(catUserbasicTable.getOpenId())){
                iCatUserbasicTableService.insertCatUserbasicTable( catUserbasicTable);
            }
            String token = "";
            wxLoginUser.setOpenId(wxUserInfoRO.getUnionid());
            wxLoginUser.setUserId(catUserbasicTable.getId());
            token =  wxTokenService.createToken(wxLoginUser);
            map1.put("token",token);
            return success(map1);
        }else{
            String token = "";
            wxLoginUser.setOpenId(wxUserInfoRO.getUnionid());
            wxLoginUser.setUserId(catUserbasicTable.getId());
            token =  wxTokenService.createToken(wxLoginUser);
            map1.put("token",token);
            return success(map1);
        }
    }

    @ApiOperation("活动新增抽奖数量")
    @PostMapping("updateInvite")
    public AjaxResult updateInvite (HttpServletRequest request,@Validated @RequestBody LoginVO loginVO){
        WxLoginUser wxLoginUser = wxTokenService.getWxUser(request);
        log.info("活动新增抽奖数量====--------{}",loginVO);
        if(loginVO.getArticleId() != null){
            CatActivityTable catActivityTable = iCatActivityTableService.selectCatActivityTableById(loginVO.getArticleId());
            if(catActivityTable != null){
                if (catActivityTable.getInviteChance() != null && catActivityTable.getInviteChance() > 0){
                    CatChance catCha1 = new CatChance();
                    catCha1.setUserId(wxLoginUser.getUserId());
                    catCha1.setArticleId(loginVO.getArticleId());
                    List<CatChance> catChances1 = catChanceService.selectCatChanceList(catCha1);

                    if (catChances1.size() > 0) {
                        // 当前用户已经助力过，不增加抽奖数量
                        return success();
                    }else{
                        CatChance ce = new CatChance();
                        ce.setUserId(wxLoginUser.getUserId());
                        ce.setArticleId(loginVO.getArticleId());
                        ce.setRemainingChances(catActivityTable.getFirstChance());
                        ce.setReferenceId(loginVO.getReferenceId());
                        log.info("走到这个新增抽奖数量4444====--------{}",ce);
                        catChanceService.insertCatChance(ce);
                    }

                    Long invite = catActivityTable.getInviteChance();
                    CatChance catCha = new CatChance();
                    catCha.setUserId(loginVO.getReferenceId());
                    catCha.setArticleId(loginVO.getArticleId());
                    List<CatChance> catChances = catChanceService.selectCatChanceList(catCha);
                    CatShareuserTable catShareuserTable = new CatShareuserTable();
                    catShareuserTable.setArticleId(loginVO.getArticleId());
                    catShareuserTable.setUserId(wxLoginUser.getUserId());
                    catShareuserTable.setType("2");
                    CatShareuserTable catShareuserTable1 = catShareuserTableService.getShareUser(catShareuserTable);
                    log.info("活动新增抽奖数量1====--------{}",catChances);
                    if (!catChances.isEmpty() && catShareuserTable1 == null) {
                        CatChance ce = new CatChance();
                        ce.setRemainingChances(invite);
                        ce.setUserId(loginVO.getReferenceId());
                        ce.setArticleId(loginVO.getArticleId());
                        ce.setReferenceId(loginVO.getReferenceId());
                        log.info("活动新增抽奖数量2111====--------{}",ce);
                        if (!Objects.equals(loginVO.getReferenceId(), wxLoginUser.getUserId())){
                            Integer i = catChanceService.updateRemainingChances(ce);
                        }
                        log.info("7777779====--------{}",catShareuserTable);
                       // Integer i = catChanceService.updateRemainingChances(ce);
                     //   CatShareuserTable catShareuserTable2 = new CatShareuserTable();
                        catShareuserTableService.insertCatShareuserTable(catShareuserTable);

                       // return success(i);
                    }else{
                        CatChance ce1 = new CatChance();
                        ce1.setRemainingChances(invite);
                        ce1.setUserId(loginVO.getReferenceId());
                        ce1.setArticleId(loginVO.getArticleId());
                       // ce1.setReferenceId(loginVO.getReferenceId());
                        log.info("走到这个新增抽奖数量111====--------{}",ce1);
                        if (!Objects.equals(loginVO.getReferenceId(), wxLoginUser.getUserId())){
                            Integer i = catChanceService.updateRemainingChances(ce1);
                        }
                    }
                }
            }else{
                return error("活动不存在");
            }
        }
        return success();
    }



    @ApiOperation("获取openId")
    @PostMapping("getOpenId")
    public AjaxResult getOpenId(@Validated @RequestBody LoginVO loginVO){
        JSONObject jsonObject = getAccessToken(loginVO.getCode());
        log.info("jsonObject登录相关的内容====--------{}",loginVO);

        String accessToken = jsonObject.getString("access_token");
        String openid = jsonObject.getString("openid");
        JSONObject jsonObject1 = getUserinfo(accessToken, openid);

        log.info("jsonObject登录相关的内容====--------{}",jsonObject1.toJSONString());
        // 检查 jsonObject 中是否包含 unionid
        if (jsonObject != null && jsonObject.containsKey("unionid")) {
            String unionid = jsonObject.getString("unionid");
            CatUserbasicTable catUserbasicTable = iCatUserbasicTableService.getUnionId(unionid);
            log.info("catUserbasicTable登录相关的内容====--------{}",catUserbasicTable);
            if (catUserbasicTable != null && StringUtils.isNotEmpty(catUserbasicTable.getProfileImg())) {
                // 检查 jsonObject 中是否包含 access_token 和 openid
                if (jsonObject.containsKey("access_token") && jsonObject.containsKey("openid")) {
//                    String accessToken = jsonObject.getString("access_token");
//                    String openid = jsonObject.getString("openid");
//                    JSONObject jsonObject1 = getUserinfo(accessToken, openid);
                    if (jsonObject1 != null && jsonObject1.containsKey("headimgurl") && jsonObject1.containsKey("nickname")) {
                        String headimgurl = jsonObject1.getString("headimgurl");
                        String nickname = jsonObject1.getString("nickname");
                        catUserbasicTable.setProfileImg(headimgurl);
                        catUserbasicTable.setNickName(nickname);
                        log.info("catUserbasicTable登录相关的内容====--------{}",catUserbasicTable);
                        iCatUserbasicTableService.updateCatUserbasicTable(catUserbasicTable);
                    }
                }
            }else{
                catUserbasicTable = new CatUserbasicTable();
                catUserbasicTable.setOpenId(jsonObject.getString("unionid"));
                String headimgurl = jsonObject1.getString("headimgurl");
                String nickname = jsonObject1.getString("nickname");
                catUserbasicTable.setProfileImg(headimgurl);
                catUserbasicTable.setNickName(nickname);
                catUserbasicTable.setReferenceId(loginVO.getReferenceId());
                catUserbasicTable.setReferenceNum(ReferralCodeGenerator.generateReferralCode());
                catUserbasicTable.setType("2");
                iCatUserbasicTableService.insertCatUserbasicTable( catUserbasicTable);

            }
        }
        return success(jsonObject);
    }


    @ApiOperation("api-根据加密id获取appid和秘钥")
    @PostMapping("getAppId")
    public AjaxResult getAppId(HttpServletRequest request,@RequestBody AppIdVO appIdVO) {
        String timeStamp = OrderUtil.timestamp10();
        String nonceStr = RandomStringUtils.randomAlphanumeric(32);
        AppIdDTO appIdDTO = new AppIdDTO();
        appIdDTO.setAppId(appid1);
        appIdDTO.setAppSecret(secret1);
        appIdDTO.setTimeStamp(timeStamp);
        appIdDTO.setNonceStr(nonceStr);
        Map<String, String> wxPayMap = new HashMap<>();
        wxPayMap.put("appId", appIdDTO.getAppId());
        // wxPayMap.put("appSecret", appIdDTO.getAppSecret());
        wxPayMap.put("timeStamp", timeStamp);
        wxPayMap.put("nonceStr", nonceStr);
        String sign = "";
        try {
            String token = getAccessToken(appIdDTO.getAppId(), appIdDTO.getAppSecret());
            System.out.println("0000000000000000---->" + token);
            String jsapiTicket = getJsapiTicket(token);
            System.out.println("0000000000000000---->" + jsapiTicket);
            String str = "jsapi_ticket=" + jsapiTicket +
                    "&noncestr=" + nonceStr +
                    "&timestamp=" + timeStamp +
                    "&url=" + appIdVO.getUrl();


            System.out.println("------->" + str);

            // SHA1签名
            String signature = DigestUtils.sha1Hex(str);
            appIdDTO.setSign(signature);
        }catch (Exception e){
            e.printStackTrace();
        }
        return success(appIdDTO);
    }

    @Autowired
    private ICatOutsiderealmTableService iCatOutsiderealmTableService;

    @ApiOperation("api-根据加密id获取appid和秘钥")
    @PostMapping("getAppIdCode")
    public AjaxResult getAppIdCode(HttpServletRequest request,@RequestBody AppIdVO appIdVO) {
        String timeStamp = OrderUtil.timestamp10();
        String nonceStr = RandomStringUtils.randomAlphanumeric(32);
        String ids = appIdVO.getActivityId();
        String id = Base64Util.decryptNumber(ids);
        CatOutsiderealmTable catOutsiderealmTable =  iCatOutsiderealmTableService.selectCatOutsiderealmByActivityId(Long.parseLong(id));
        log.info("catOutsiderealmTable登录相关的内容 新增 ====--------{}",catOutsiderealmTable);
        AppIdDTO appIdDTO = new AppIdDTO();
        //catOutsiderealmTable.getAppId();
        // catOutsiderealmTable.getAppSecret();
        if (catOutsiderealmTable != null && catOutsiderealmTable.getAppId() != null) {
            appIdDTO.setAppId(catOutsiderealmTable.getAppId());
        } else {
            appIdDTO.setAppId(appid);
        }
        // 判断 catOutsiderealmTable 是否为 null 且 getAppSecret 方法返回值不为 null
        if (catOutsiderealmTable != null && catOutsiderealmTable.getAppSecret() != null) {
            appIdDTO.setAppSecret(catOutsiderealmTable.getAppSecret());
        } else {
            appIdDTO.setAppSecret(secret);
        }
        // appIdDTO.setAppId(appid);
        // appIdDTO.setAppSecret(secret);
        appIdDTO.setTimeStamp(timeStamp);
        appIdDTO.setNonceStr(nonceStr);
        Map<String, String> wxPayMap = new HashMap<>();
        wxPayMap.put("appId", appIdDTO.getAppId());
        // wxPayMap.put("appSecret", appIdDTO.getAppSecret());
        wxPayMap.put("timeStamp", timeStamp);
        wxPayMap.put("nonceStr", nonceStr);
        String sign = "";
        try {
            String token = getAccessToken(appIdDTO.getAppId(), appIdDTO.getAppSecret());
            System.out.println("0000000000000000---->" + token);
            String jsapiTicket = getJsapiTicket(token);
            System.out.println("0000000000000000---->" + jsapiTicket);
            String str = "jsapi_ticket=" + jsapiTicket +
                    "&noncestr=" + nonceStr +
                    "&timestamp=" + timeStamp +
                    "&url=" + appIdVO.getUrl();


            System.out.println("------->" + str);

            // SHA1签名
            String signature = DigestUtils.sha1Hex(str);
            appIdDTO.setSign(signature);
        }catch (Exception e){
            e.printStackTrace();
        }
        return success(appIdDTO);
    }


    public String getJsapiTicket(String accessToken) {
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="
                + accessToken + "&type=jsapi";
        String result = HttpUtil.get(url);
        System.out.println("微信jsapi_ticket------------->"+result);
        JSONObject json = JSONObject.parseObject(result);
        return json.getString("ticket");
    }

    public String getAccessToken(String appId, String appSecret) {
        String redisKey = TOKEN_KEY_PREFIX + appId;

        // 从缓存获取token
        String accessToken = redisCache.getCacheObject(redisKey);
        if (StringUtils.isNotEmpty(accessToken)) {
            // 获取剩余过期时间
            Long expire = redisCache.getExpire(redisKey);
            // 如果token存在且未到提前刷新时间，直接返回
            if (expire != null && expire > REFRESH_BEFORE_EXPIRE) {
                return accessToken;
            }
        }

        // 缓存中不存在或即将过期，重新获取
        synchronized (this.getClass()) {
            // 双重检查
            accessToken = redisCache.getCacheObject(redisKey);
            if (StringUtils.isNotEmpty(accessToken)) {
                Long expire = redisCache.getExpire(redisKey);
                if (expire != null && expire > REFRESH_BEFORE_EXPIRE) {
                    return accessToken;
                }
            }

            try {
                String newToken = getStableAccessToken(appId, appSecret);
                if (StringUtils.isNotEmpty(newToken)) {
                    // 存入缓存并设置过期时间
                    redisCache.setCacheObject(redisKey, newToken, EXPIRE_SECONDS, TimeUnit.SECONDS);
                    return newToken;
                }
            } catch (Exception e) {
                log.error("获取微信access_token失败", e);
                // 如果获取新token失败但缓存中还有旧token，返回旧token
                if (StringUtils.isNotEmpty(accessToken)) {
                    return accessToken;
                }
                throw new RuntimeException("获取微信access_token失败", e);
            }
        }
        return null;
    }


    private String getStableAccessToken(String appId, String appSecret) {
        String url = "https://api.weixin.qq.com/cgi-bin/stable_token";

        JSONObject requestBody = new JSONObject();
        requestBody.put("grant_type", "client_credential");
        requestBody.put("appid", appId);
        requestBody.put("secret", appSecret);

        String result = HttpUtil.post(url, requestBody.toString());
        log.info("微信stable token响应------------->"+result);

        JSONObject json = JSONObject.parseObject(result);
        if (json.containsKey("access_token")) {
            return json.getString("access_token");
        }

        throw new RuntimeException("获取access_token失败: " + result);
    }



/*    public  String getOpenId(String loginCode) {
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        String requestUrl = UriComponentsBuilder.fromHttpUrl(url)
                .queryParam("appid", appid)
                .queryParam("secret", secret)
                .queryParam("js_code", loginCode)
                .queryParam("grant_type", "authorization_code")
                .toUriString();
        System.out.println("--------lianjie--------,"+requestUrl);
        HttpResponse response = HttpUtil.createGet(requestUrl).execute();
        // 获取 session_key 和 openid
        JSONObject parseObj = JSONUtil.parseObj(response.body());
        System.out.println("----------------,"+parseObj.toString());
        String openid = (String) parseObj.get("openid");
        return openid;
    }*/


    public JSONObject getOpenId(String code) {

        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid
                + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";
        PrintWriter out = null;
        BufferedReader in = null;
        String line;
        StringBuffer stringBuffer = new StringBuffer();
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();

            // 设置通用的请求属性 设置请求格式
            //设置返回类型
            conn.setRequestProperty("contentType", "text/plain");
            //设置请求类型
            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
            //设置超时时间
            conn.setConnectTimeout(1000);
            conn.setReadTimeout(1000);
            conn.setDoOutput(true);
            conn.connect();
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应    设置接收格式
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), "UTF-8"));
            while ((line = in.readLine()) != null) {
                stringBuffer.append(line);
            }
            JSONObject jsonObject = JSONObject.parseObject(stringBuffer.toString());
            System.out.println("------这里是-------"+jsonObject);
            return jsonObject;

        } catch (Exception e) {
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }


    public JSONObject getAccessToken(String code) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token"
                + "?appid=" + appid1
                + "&secret=" + secret1
                + "&code=" + code
                + "&grant_type=authorization_code";

        PrintWriter out = null;
        BufferedReader in = null;
        StringBuffer stringBuffer = new StringBuffer();

        try {
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();

            // 设置请求属性
            conn.setRequestProperty("contentType", "text/plain");
            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.setDoOutput(true);
            conn.connect();

            // 获取输出流
            out = new PrintWriter(conn.getOutputStream());
            out.flush();

            // 读取响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                stringBuffer.append(line);
            }

            JSONObject jsonObject = JSONObject.parseObject(stringBuffer.toString());
            // 返回示例:
            // {
            //    "access_token":"ACCESS_TOKEN",
            //    "expires_in":7200,
            //    "refresh_token":"REFRESH_TOKEN",
            //    "openid":"OPENID",
            //    "scope":"SCOPE"
            // }
            return jsonObject;

        } catch (Exception e) {
            logger.error("获取网页授权access_token异常", e);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                logger.error("关闭流异常", ex);
            }
        }
        return null;
    }


    public JSONObject getUserinfo(String token, String openid) {
        String url = "https://api.weixin.qq.com/sns/userinfo"
                + "?access_token=" + token
                + "&openid=" + openid
                + "&lang=zh_CN";
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuffer stringBuffer = new StringBuffer();

        logger.info("获取用户信息url: {}", url);

        try {
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();

            // 设置请求属性
            conn.setRequestProperty("contentType", "text/plain");
            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.setDoOutput(true);
            conn.connect();

            // 获取输出流
            out = new PrintWriter(conn.getOutputStream());
            out.flush();

            // 读取响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                stringBuffer.append(line);
            }

            JSONObject jsonObject = JSONObject.parseObject(stringBuffer.toString());
            // 返回示例:
            // {
            //    "access_token":"ACCESS_TOKEN",
            //    "expires_in":7200,
            //    "refresh_token":"REFRESH_TOKEN",
            //    "openid":"OPENID",
            //    "scope":"SCOPE"
            // }
            return jsonObject;

        } catch (Exception e) {
            logger.error("获取网页授权access_token异常", e);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                logger.error("关闭流异常", ex);
            }
        }
        return null;
    }

    /**
     * 获取用户信息
     */
    public JSONObject getUserInfo(String accessToken, String openId) {
        String url = "https://api.weixin.qq.com/sns/userinfo"
                + "?access_token=" + accessToken
                + "&openid=" + openId
                + "&lang=zh_CN";

        PrintWriter out = null;
        BufferedReader in = null;
        StringBuffer stringBuffer = new StringBuffer();

        try {
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();

            // 设置请求属性
            conn.setRequestProperty("contentType", "text/plain");
            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.setDoOutput(true);
            conn.connect();

            // 获取输出流
            out = new PrintWriter(conn.getOutputStream());
            out.flush();

            // 读取响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                stringBuffer.append(line);
            }

            JSONObject jsonObject = JSONObject.parseObject(stringBuffer.toString());
            // 返回示例:
            // {
            //    "openid":"OPENID",
            //    "nickname":"NICKNAME",
            //    "sex":1,
            //    "province":"PROVINCE",
            //    "city":"CITY",
            //    "country":"COUNTRY",
            //    "headimgurl": "HEADIMGURL",
            //    "privilege":[],
            //    "unionid": "UNIONID"
            // }
            return jsonObject;

        } catch (Exception e) {
            logger.error("获取用户信息异常", e);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                logger.error("关闭流异常", ex);
            }
        }
        return null;
    }


    @ApiOperation("修改用户信息")
    @PostMapping("userinfo")
    public AjaxResult userinfo(HttpServletRequest request, @Validated @RequestBody WxUserVO wxUserVO){
        WxLoginUser wxLoginUser = wxTokenService.getWxUser(request);
        CatUserbasicTable shoppingUser = new CatUserbasicTable();
        shoppingUser.setId(wxLoginUser.getUserId());
        shoppingUser.setPhone(wxUserVO.getPhone());
        shoppingUser.setGender(wxUserVO.getGender());
        shoppingUser.setUserArea(wxUserVO.getUserArea());
        shoppingUser.setNickName(wxUserVO.getNickName());
        shoppingUser.setProfileImg(wxUserVO.getProfileImg());
        return success(iCatUserbasicTableService.updateCatUserbasicTable(shoppingUser));
    }


    @ApiOperation(value = "获取用户详细")
    @GetMapping("/getUserDetalis")
    public AjaxResult getUserDetalis(HttpServletRequest request) throws IOException
    {
        WxLoginUser wxLoginUser = wxTokenService.getWxUser(request);
        return success(iCatUserbasicTableService.selectCatUserbasicTableById(wxLoginUser.getUserId()));
    }

    @GetMapping("/qrcode")
    public ResponseEntity<byte[]> generateQRCode(
            @RequestParam(value = "userId", defaultValue = "")Long userId,
            @RequestParam(value = "size", defaultValue = "400",required = false) int size) {
        try {

            CatUserbasicTable catUserbasicTable = iCatUserbasicTableService.selectCatUserbasicTableById(userId);

            // 设置二维码参数
            Map<EncodeHintType, Object> hints = new HashMap<>();
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); // 设置纠错级别
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 设置编码
            hints.put(EncodeHintType.MARGIN, 2); // 设置边距

            String content = "?userId="+userId+"&referenceNum="+catUserbasicTable.getReferenceNum();

            // 创建二维码
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, size, size, hints);

            // 将二维码转换为图片
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(bitMatrix, "PNG", outputStream);
            byte[] qrCodeImage = outputStream.toByteArray();

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_PNG);
            headers.setContentLength(qrCodeImage.length);

            // 返回二维码图片
            return new ResponseEntity<>(qrCodeImage, headers, HttpStatus.OK);

        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(("Error generating QR code: " + e.getMessage()).getBytes());
        }
    }

    @GetMapping("/getUserList")
    public  AjaxResult getUserList(HttpServletRequest request) throws IOException
    {
        WxLoginUser wxLoginUser = wxTokenService.getWxUser(request);
        return success(iCatUserbasicTableService.countByReferenceData(wxLoginUser.getUserId()));
    }


}
